import sys
import os
sys.path.append(os.path.abspath(os.path.dirname(__file__)) + "/..")
from stock.stock_utils import *
from stock.stockbase import *
import pandas as pd

lmin = 20
lmax = 80

FSM_STATUS_IDLE = 0
FSM_STATUS_LOW = 1
FSM_STATUS_HIGH = 2
class SimulateStock(StockBase):
    """SimulateStock obj"""
    def __init__(self, code, cycle, num):
        super().__init__(code, cycle=cycle, num=num)
        self.df = None
        self.money_base = 100000.0
        self.money_total = 0.0
        self.cost_rate = 0.002
        self.stock_nums = 0
        self.buy_price = 0.0
        self.buy_index = 0
        self.sell_price = 0.0
        self.sell_index = 0
        self.status = FSM_STATUS_IDLE
        self.buyed = False
        self.bsnode = []
        self.haskdj = False

    def GetKdjData(self):
        if self.data == None:
            return False
        self.df = get_kdj_data(self.data)
        self.haskdj = True
        
        return True

    def doSell(self, index, c):
        if self.buyed == True:
            self.buyed = False
            cur = self.stock_nums * c * (1 - self.cost_rate)
            self.sell_price = c
            self.sell_index = index
            self.money_total += cur
            lt = self.buy_price * self.stock_nums
            st = {"buy_index":self.buy_index, 
            "sell_index":self.sell_index, 
            "buy_price":self.buy_price, 
            "sell_price":self.sell_price,
            "stock_nums":self.stock_nums,
            "get":int(cur - lt),
            "ok":self.sell_price > self.buy_price}
            self.bsnode.append(st)

            self.stock_nums = 0
            # print("index %d goto sell and money change from %d to %d diff=%d and price change from %f to %f diff %f"%
            # (index, int(lt), int(cur), int(cur - lt), self.buy_price, self.sell_price, (self.sell_price - self.buy_price)))

    def doBuy(self, index, c):
        if self.buyed == False:
            self.buyed = True
            self.stock_nums = int(int(self.money_total/c)/100)*100
            cost = self.stock_nums * c
            self.money_total -= cost
            self.buy_price = c
            self.buy_index = index
            # print("index %d goto buy nums = %d and cost=%d price %f"%(index, self.stock_nums, int(cost), c))
    
    def statShow(self):
        okn = 0
        errorn = 0
        # print("goto status:")
        itemnode = []
        bifirst = 0
        silast = 0
        for v in self.bsnode:
            bi = v["buy_index"]
            si = v["sell_index"]
            if bifirst == 0:
                bifirst = bi
            if silast < si:
                silast = si
            bt = self.df.index[bi]
            st = self.df.index[si]
            sn = v["stock_nums"]
            get = v["get"]
            bp = v["buy_price"]
            costm = bp * sn
            item = {}
            item["bt"] = bt
            item["st"] = st
            item["ct"] = si - bi
            item["get"] = get
            item["costm"] = costm
            itemnode.append(item)
            # print("from %d(%s) to %d(%s) stock_nums %d cost money %d get %d and cost days %d"%
            # (bi, bt, si, st, sn, costm, get, si-bi))
            if v["ok"] == True:
                okn += 1
            else:
                errorn += 1
        # print("total from %d to %d okn=%d errorn=%d"%(self.money_base, self.money_total, okn, errorn))
        ret = {}
        ret["okn"] = okn
        ret["errorn"] = errorn
        ret["bi"] = bifirst
        ret["si"] = silast
        ret["money_begin"] = self.money_base
        ret["money_total"] = self.money_total
        ret["itemnode"] = itemnode
        if self.haskdj == True:
            ret["k"] =  self.df["K"][-1]
            ret["Lk"] =  self.df["K"][-2]
            ret["D"] =  self.df["D"][-1]
            ret["LD"] =  self.df["D"][-2]
            ret["J"] =  self.df["J"][-1]
            ret["LJ"] = self.df["J"][-2]
        return ret

    def KdjGetDF(self):
        if self.GetData() == False:
            return False
        if self.GetKdjData() == False:
            return False
        if len(self.df) < 9:
            return False

        return True
    
    def KdjProc(self):
        if self.GetData() == False:
            return None
        if self.GetKdjData() == False:
            return None
        if len(self.df) < 9:
            return None
        # print(self.df)
        #以k值为准
        self.money_total = self.money_base
        for i in range(0, len(self.df)):
            v = self.df["J"][i]
            c = self.df["close"][i]
            if self.status == FSM_STATUS_IDLE:
                if v <= lmin:
                    self.status = FSM_STATUS_LOW
                    # print("index %d idle to low"%(i))
                    self.doSell(i, c)
                elif v >= lmax:
                    self.status = FSM_STATUS_HIGH
                    # print("index %d idle to high"%(i))
            elif self.status == FSM_STATUS_LOW:
                if v > lmin:
                    # print("index %d low to idle"%(i))
                    self.status = FSM_STATUS_IDLE
                    self.doBuy(i, c)
            elif self.status == FSM_STATUS_HIGH:
                if v < lmax:
                    # print("index %d high to idle"%(i))
                    self.status = FSM_STATUS_IDLE
                    self.doSell(i, c)

        self.doSell(len(self.df) - 1, c)
        return self.statShow()
